home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cnstrnts / thinglab.lha / ThingLabII / ThingManual.text < prev    next >
Text File  |  1993-07-24  |  32KB  |  688 lines

  1. 0. Disclaimer
  2.  
  3. ThingLab II is a research prototype and, as such, it's goal is to 
  4. demonstrate concepts rather than to provide the world with a 
  5. polished user interface construction tool. Thus, while we have tried 
  6. to make it usable, it still has obvious  blemishes and missing features  
  7. and probably numerous bugs. We hope that you will see in ThingLab 
  8. II the potential usefulness of constraints rather than the limitations 
  9. of a particular system.
  10.  
  11. This manual was, of necessity, written in haste. We hope that this, 
  12. too, will be forgiven. The alternative was to provide no manual at 
  13. all!
  14.  
  15. 1. Introduction
  16.  
  17. ThingLab II supports the exploration of constraint-based user 
  18. interfaces. It consists of a set of classes that define constraints and 
  19. constrainable objects called things. It also includes an incremental 
  20. constraint satisfier, a module compiler, a construction-set style user 
  21. interface, various tools, and an extensible set of primitive user 
  22. interface building blocks.
  23.  
  24. ThingLab II uses the dataflow constraint model. In this model, a 
  25. constraint is a collection of functions that use some subset of the 
  26. constrained variables as inputs and compute the remainder as 
  27. outputs. Each of these functions, called constraint methods (or 
  28. methods, for short), can be executed to enforce the relationship 
  29. represented by the constraint. For example, the constraint:
  30.  
  31.     a = b + c
  32.  
  33. has three constraint methods:
  34.  
  35.     a := b + c
  36.     b := a - c
  37.     c  := a - b.
  38.  
  39. Dataflow constraints can be used over a wide range of data types. 
  40. For example, ThingLab II includes constraints that operate on 
  41. numbers, bitmaps, strings, and lists. Dataflow constraints can also 
  42. be executed efficiently. However, they are not as powerful as some 
  43. other kinds of constraints. For example, they cannot be used for 
  44. linear programming, linear algebra, or scheduling problems. 
  45. Furthermore, the particular dataflow constraint solver in ThingLab 
  46. II cannot handle inequality constraints such as "x < 10" and is not 
  47. guaranteed to find a solution if the constraint graph contains cycles. 
  48. These limitations, along with the decision to use dataflow 
  49. constraints in the first place, represent deliberate engineering 
  50. choices. We believe that dataflow constraints, even with our 
  51. restrictions, are sufficiently powerful for most user interface 
  52. applications and the restrictions permit them to be implemented 
  53. extremely efficiently. However, it is important to keep its limitations 
  54. in mind to avoid asking ThingLab II to solve problems that it was not 
  55. designed to handle.
  56.  
  57. The remainder of this manual presents a tutorial example, expands 
  58. upon some of the basic concepts of ThingLab II, and briefly describes 
  59. how to operate some of the tools. An appendix describes how to file 
  60. ThingLab II into a Smalltalk-80 image.
  61.  
  62. 2. Getting Started
  63.  
  64. To get started, invoke the "ThingLabII Parts Bin" item in the 
  65. background menu. This gives you a view (i.e. a window) on the root 
  66. of the parts bin hierarchy. There is initially only one parts bin, "All 
  67. Parts," containing all the primitive Things. The "All Parts" bin will be 
  68. updated as you work to contain all new Things you create. Open "All 
  69. Parts" by selecting it and using the "open" menu item or by double-
  70. clicking. You should see a bunch of named icons like PointThing, 
  71. LineThing, Sum, and MidPoint. These are primitive things.
  72.  
  73. Hint: Because the Mac mouse has only one button you can get the 
  74. middle-button (yellow) menu by pressing the red button over the title 
  75. area of a ThingLabII window. The right-button (blue) menu is also 
  76. available in the gray area around the title. This shortcut is not very 
  77. useful on machines with three button mice!
  78.  
  79. Now create a new, empty thing by invoking the "new thing" menu 
  80. item in one of the parts bin windows. Note that the new thing is 
  81. given a unique name such as "Thing1" and an icon for it appears in 
  82. "All Parts." The new thing's name and default icon may both be 
  83. changed, if desired, by selecting the thing's icon in "All Parts" and 
  84. invoking the appropriate operation from the menu.
  85.  
  86. Components are added to the new thing by dragging them from a 
  87. parts bin into the thing construction view. There is a modal dialogue 
  88. involved when inserting new components. After you've dragged a 
  89. group of components into the target thing and released the mouse 
  90. button, the system expects you to specify where to place the parts by 
  91. clicking the mouse once for each part. Add HLine and VLine things to 
  92. the new thing and then pick up the endpoint of one of the lines with 
  93. the mouse and move it around. You will notice a heavy black square 
  94. appear when you move the point over any other point. This indicates 
  95. that the points may be glued together ("merged"). If you release the 
  96. mouse at this point, the merge will be done. You should now be able 
  97. to construct simple polygons and rectangles (using LineThings, 
  98. HLines, and VLines). Try it.
  99.  
  100. 3. Concepts
  101.  
  102. Things
  103.  
  104. The primitive elements of the ThingLabII constraint programming 
  105. system are variables and constraints. The unit of encapsulation used 
  106. to assemble these elements into higher-level objects is the thing. A 
  107. thing has a collection of parts, where each part is either a primitive 
  108. variable or another thing. For example, a Node thing is composed of 
  109. a primitive variable named ╘value╒ and a Point thing named 
  110. ╘location╒. This Point thing is in turn composed of two primitive 
  111. variables, named ╘x╒ and ╘y╒. In addition to its parts, a thing may also 
  112. have a set of constraints that define relationships among its parts 
  113. and subparts. For example, a HLine thing has such a constraint 
  114. stating that the y values of its two endpoint Point things should be 
  115. equal.
  116.  
  117. Cloning
  118.  
  119. New instances of things are created by copying an existing instance 
  120. called the prototype. When a thing is copied, its structure of parts 
  121. and subparts is copied all the way down to the leaves and its 
  122. constraints are copied and installed in the new thing. The copying 
  123. process is called cloning. A new kind of thing is created by starting 
  124. with a new, empty thing, copying previously created things into it, 
  125. and connecting these things together with constraints. The resulting 
  126. object is then the prototype for the new type of thing.
  127.  
  128. Merging
  129.  
  130. Identity relationships between parts of a thing may be established via 
  131. merges. A merge, which may be thought of as a special sort of 
  132. constraint, equates two subpart trees so that they become a single, 
  133. shared part. After two subparts are merged, all constraints from the 
  134. original subparts are applied to the new shared part. For example, 
  135. the endpoints of two Line things might be merged. If the merged 
  136. point is then dragged, both lines will be affected. Furthermore, if one 
  137. of the original Line things was constrained to be horizontal and the 
  138. other was constrained to be vertical, the merged point will now be 
  139. governed by both constraints.
  140.  
  141. The Construction Kit Metaphor
  142.  
  143. The construction kit metaphor for thing construction has proven to 
  144. be a powerful mechanism for packaging and reusing constraint 
  145. ╥programs.╙ For example, a Quadrilateral may be constructed from 
  146. four Line things. The Quadrilateral may be turned into a Rectangle 
  147. by adding two horizontal and two vertical constraints. A center may 
  148. be added by stretching a MidPoint thing across the diagonal. Finally, 
  149. the centers and corners of several instances of the resulting 
  150. CenterRectangle may be combined with additional vertical and 
  151. horizontal constraints to produce a set of aligned boxes for a 
  152. diagram or a paned-window layout. Note that many of the 
  153. intermediate stages in this construction ╤ Quadrilaterals, 
  154. Rectangles, and CenterRectangles ╤ are re-usable objects in their 
  155. own right.
  156.  
  157. Symbolic Strengths
  158.  
  159. Constraint strengths are specified using Symbol objects such as 
  160. #required. These are converted into Strength objects in various data 
  161. structures. Class Strength keeps a table in a class variable that maps 
  162. symbolic names to their indices in the table, which are used to order 
  163. the set of Strengths. It is possible to insert new symbolic strengths 
  164. into this table by modifying and then invoking Strength's class 
  165. initialization method.
  166.  
  167. Constraints
  168.  
  169. Constraints may be defined either by using an equation:
  170.  
  171.     Constraint
  172.         symbols: #(a b c)
  173.         equation: 'a = (b + c)'
  174.  
  175. or by explicitly listing its constraint methods:
  176.  
  177.     Constraint
  178.         symbols: #(a b c)
  179.         methodStrings: #(
  180.             'a := b + c'
  181.             'b := a - c'
  182.             'c := a - b')
  183.  
  184. In this example, the resulting constraints would be identical. The first 
  185. form is preferred as it is compact and easy to read. There are times, 
  186. however, when the equation translator cannot find an inverse 
  187. function (such as when operating on bitmaps) or when one wishes to 
  188. make a one-directional constraint. In these situations one must 
  189. resort to the second form.
  190.  
  191. Note the parenthesis in the equation string in the first form. These 
  192. are necessary so that the top-level expression passed to the equation 
  193. translator is the "=" message send. If the parenthesis were 
  194. eliminated the top level expression would be the "+" message send, 
  195. since Smalltalk is evaluated left to right, and the equation translator 
  196. would complain. (This is a blemish; it would be easy to make the 
  197. equation translator figure this out for itself.)
  198.  
  199. Binding Constraints to Variables
  200.  
  201. Constraints are bound to their constrained objects using Reference 
  202. objects. A Reference is a rooted symbolic path to a part or subpart of 
  203. a thing. The "->" message can be sent to any thing to create a 
  204. reference to one of its parts. For example: "myThing->#line1.p1.x". 
  205. Note that the sequence of subpart names, "line1," "p1," and "x," are 
  206. represented as a single Symbol object. The symbol is broken into 
  207. components at the period characters when the Reference is created. 
  208. In some contexts, the root thing is implied, as in:
  209.  
  210.     aThing require: #node.location.x equals: #box.center.x
  211.  
  212. A previously created, unbound constraint may be bound to a set of 
  213. variable references using the message "bind:strength:", as in:
  214.  
  215.     midPointConstraint
  216.         bind: (Array
  217.             with: self->#topLeft.x
  218.             with: self->#center.x
  219.             with: self->#bottomRight.x)
  220.         strength: #required
  221.  
  222. Note that the strength must also be specified when a constraint is 
  223. bound. Often, constraints are bound when they are created, as in:
  224.  
  225.     Constraint
  226.         symbols: #(p1 midpoint p2)
  227.         equation: '(p1 + p2) // 2 = midpoint'
  228.         bind: (Array
  229.             with: mpThing->#p1.y
  230.             with: mpThing->#midpoint.y
  231.             with: mpThing->#p2.y)
  232.         strength: #stronglyPreferred
  233.  
  234. There are a number of shorthand forms for constructing and adding 
  235. constraints to a thing, such as this example from the MidPoint 
  236. primitive thing:
  237.  
  238.     mpThing
  239.         stronglyPrefer: '(p1 + p2) // 2 = midpoint'
  240.         where: #((p1 p1.y) (midpoint midpoint.y) (p2 p2.y))
  241.  
  242. Note that the strength is encoded in message selector and that the 
  243. symbolic variable names and their paths (relative to root "mpThing") 
  244. are compactly specified in the "where:" clause. Many other shorthand 
  245. forms can be found be browsing the protocols for Thing.
  246.  
  247. Adding and Removing Constraints
  248.  
  249. Confusing as it is likely to be, there are two senses in which 
  250. constraints are added and removed. First, they are added to and 
  251. removed from the constraint graph. A constraint does nothing, even 
  252. after it has been bound to its variables, until it is added to the 
  253. constraint graph with the message:
  254.  
  255.     aConstraint addConstraint
  256.  
  257. It can be deactivated again by sending it the message:
  258.  
  259.     aConstraint removeConstraint
  260.  
  261. The other sense in which constraints are added and removed has to 
  262. do with them being owned by a thing. Any thing may own a set of 
  263. constraints, and those constraints are cloned when the thing is 
  264. cloned. Constraints attached to parts of the thing but not owned by it, 
  265. such as mouse constraints, are not cloned with the thing. Constraints 
  266. may be added to and removed from things using the following 
  267. messages:
  268.  
  269.     aThing addConstraint: mpConstraint
  270.     aThing removeConstraint: mpConstraint
  271.  
  272. Adding a constraint to a thing also adds it to the constraint graph as 
  273. a side effect. (This sounds more confusing than it really is.)
  274.  
  275. Planning
  276.  
  277. One of the strengths of ThingLab II is the performance of its 
  278. incremental constraint satisfaction planner. Constraint satisfaction 
  279. is cheap enough that one may add and remove constraints 
  280. dynamically and, in fact, the ThingLabII user interface does exactly 
  281. this as the user interacts with the system. The incremental planner 
  282. maintains a data flow graph among the constraints as constraints 
  283. are added and removed. The dataflow graph represents a locally-
  284. predicate-better solution to the current set of constraints. (Since 
  285. there may be conflicts between constraints and some constraints are 
  286. stronger than others, not all the constraints will necessarily be 
  287. satisfied. For details on how and why the constraint satisfier works, 
  288. refer to the CACM article.)
  289.  
  290. The dataflow graph can be reduced to a linear list of constraint 
  291. methods called a plan. The methods of the plan are executed in order 
  292. to compute a solution to the current set of constraints. In the original 
  293. ThingLab, this list of methods would have been compiled into a 
  294. Smalltalk method. Although the code generated was quite fast, the 
  295. compilation process itself was expensive and had to be repeated each 
  296. time the constraint graph was modified.
  297.  
  298. Module Compilation
  299.  
  300. Unlike the original ThingLab, ThingLabII does not normally compile 
  301. plans into Smalltalk methods. However, when a given thing has 
  302. been developed to the point of stability and would be useful as a 
  303. building block for constructing other things, it may be compiled into a 
  304. module. A module behaves externally like the thing from which it 
  305. was compiled, but with better performance. All possible plans for 
  306. satisfying the module's internal constraints are pre-computed, 
  307. optimized, and compiled into Smalltalk methods. The module's 
  308. planning behavior is similarly pre-computed so that it appears to the 
  309. planner to have only a single (albeit complex) internal constraint.
  310.  
  311. Constructing Things
  312.  
  313. New kinds of things may be constructed either by using the direct-
  314. manipulation interface or by writing a program to do the 
  315. construction. A program can do anything that can be done using the 
  316. direct-manipulation interface plus various things which are 
  317. awkward to do via direct manipulation, such as using nested loops to 
  318. interconnect an array of components with regular structure (e.g. 
  319. laying out a chess board). The direct-manipulation interface is also 
  320. not a good vehicle for adding constraints that are not built into some 
  321. graphical object, since there is no way to view and manipulate these 
  322. ╥invisible╙ constraints. The demo classes are examples of how to 
  323. construct things using programs.
  324.  
  325. Adding Primitive Things
  326.  
  327. A new primitive thing is added by creating a new subclass of 
  328. PrimitiveThing. Three initialization methods are used to define the 
  329. structure of the new thing:
  330.  
  331.     initializeStructure,
  332.     initializeConstraints, and
  333.     initializeValues.
  334.  
  335. The parts of the thing are defined in initializeStructure. Any part that 
  336. holds a thing must be initialized here. Instance variables not 
  337. initialized to be things are assumed to hold non-thing values which 
  338. do not need to be recursively copied during cloning. Constraints are 
  339. defined in initializeConstraints. Finally, initial values are declared in 
  340. initializeValues. Any of these initialization methods may be omitted if 
  341. desired; the default behavior is to do nothing.
  342.  
  343. By convention, all primitive things have a class initialization method 
  344. that initializes their icon bitmap for the parts bin and their 
  345. explanation string. The class initialization method must do "self 
  346. initializePrimitive" before doing anything else. If the class 
  347. initialization method is omitted, a default method provides a generic 
  348. icon bitmap and explanation string.
  349.  
  350. If the new primitive is to have custom appearance, it must supply a 
  351. display method and various other glyph protocol methods. Likewise, 
  352. if it to have custom mouse or keyboard input behavior, it must supply 
  353. methods to support this behavior. Unfortunately, although it is not 
  354. difficult, it is beyond the scope of the introductory manual to describe 
  355. in detail how to add such behavior. The best way to learn how to do 
  356. it is to read the comments in class Thing and study the supplied 
  357. primitive things.
  358.  
  359. Time and State
  360.  
  361. ThingLabII captures the notion of state changes in time via a 
  362. mechanism called history variables. A history variable stores not only 
  363. its current value, but some fixed number of past values as well. 
  364. Constraints may refer to the values of previous states but may not 
  365. alter them. This forces time to always move forward and allows the 
  366. implementation to truncate histories at some reasonable limit. A 
  367. system clock advances the histories of all history variables in a given 
  368. thing as a single atomic operation.
  369.  
  370. This simple model allows one to elegantly express time-dependent 
  371. behavior. For example, a time-varying variable can be integrated by 
  372. using a Sum constraint to add its current value to the previous value 
  373. of the variable containing the integral. Similarly, the discrete-time 
  374. derivative of a time-dependent variable can be computed by taking 
  375. the difference between successive states. More relevant to user 
  376. interface construction, one can build finite state machines for 
  377. processing user inputs or producing simple animations. As another 
  378. example, the browser demo uses the history mechanism to pre-select 
  379. the most recently selected message category and message pane 
  380. selections, if possible, when the class pane selection is changed.
  381.  
  382. Constraints and Imperative Code
  383.  
  384. A user interface must inform the application program of user actions. 
  385. Similarly, the application program will take actions, autonomously 
  386. or in response to user actions, that will effect the graphical objects 
  387. visible in the user interface.
  388.  
  389. It is best to think of the world in two parts: the world of constraints 
  390. and constrained variables (the constraint world) and the less 
  391. disciplined world of normal Smalltalk programs (the imperative 
  392. world). The imperative world is in control but interacts with the 
  393. constraint world by:
  394.  
  395.     1. instantiating a set of variables,
  396.     2. adding and removing constraints on those variable,
  397.     3. examining the values of constrained variables,
  398.     4. changing the values of constrained variables, and
  399.     5. invoking the constraint satisfaction machinery.
  400.  
  401. Interacting with the graphical objects of a user interface occurs 
  402. through a Smalltalk View-Controller pair that knows about the 
  403. constraint world. For example, moving a point causes mouse 
  404. constraints to be added to the point, all constraints to be repeatedly 
  405. satisfied as the mouse moves, and the mouse constraints to be 
  406. removed at the end of the interaction. The ThingLab II user interface 
  407. framework has hooks that allows custom widgets, such as sliders 
  408. and buttons, to be handled in a similar manner. Thus, the ThingLab II 
  409. UI is simply a special imperative program that interacts with the 
  410. constraint world.
  411.  
  412. The application program may also interact with the constraint 
  413. world. The rules for this are simple. Any variable may be examined 
  414. at any time. However, the application must be only change the 
  415. values of variables in a way that allows constraints on the variable 
  416. to be kept satisfied as well as possible. One way to do this is with the 
  417. set:to:strength: message. For example, one could write:
  418.  
  419.     p set: #x to: 15 strength: #preferred
  420.  
  421. This statement can be read: ╥I would prefer that the x part of point p 
  422. be 15 now.╙ It is implemented by adding an edit constraint with a 
  423. strength of preferred to the x part of p and invoking the planner. If 
  424. the planner finds a way to satisfy the edit constraint, then the value 
  425. of x is changed and the plan is executed; otherwise, the value of x is 
  426. left unchanged. Finally, the edit constraint is removed.
  427.  
  428. Because the set:to:strength: mechanism invokes the planner twice 
  429. (once to add and once to remove the edit constraint) it is not efficient 
  430. if a sequence of changes must be made to the same variable, such as 
  431. during an animation sequence or a drag interaction. In such cases, 
  432. the client program must add edit constraints for all variables that 
  433. will be changed, extract a plan, and invoke the plan after every set of 
  434. variable change. This is how the dragging is implemented in the 
  435. ThingLab II UI.
  436.  
  437. The mechanisms just described are clearly not as easy to use as one 
  438. would like and should be thought of as work in progress. Many of 
  439. the issues raised will be addressed in Bjorn Freeman-Benson╒s thesis 
  440. on constraint-imperative programming.
  441.  
  442. 4. The User Interface
  443.  
  444. Gestures
  445.  
  446. The system recognizes several different gestures made with the 
  447. mouse, namely: click, double-click, and drag. All gestures are made 
  448. with the red button of the mouse and possibly the shift key, and are 
  449. context sensitive.
  450.  
  451. A drag occurs when the mouse button is held down longer than about 
  452. a quarter second. A special kind of drag, called a "sweep", is made by 
  453. moving the mouse down and right quickly during the initial mouse 
  454. press. This is used for the "area select" operation.
  455.  
  456. Selecting
  457.  
  458. The system maintains a list of selected objects which are used as 
  459. arguments to menu commands or input actions. Sweeping is used to 
  460. select multiple objects to operated on, with feedback given by 
  461. drawing a temporary rectangle around the area to be selected. Shift-
  462. clicking or shift-sweeping toggles the selection of the designated 
  463. objects. Clicking over an object makes it the only thing selected. 
  464. Clicking over the background clears the entire selection. Double 
  465. clicking over an object "opens" it. (This is an example of gesture 
  466. whose meaning varies with context. In the parts bin, opening an 
  467. parts bin brings up a new window containing its contents while 
  468. opening a thing brings up an editor on the thing. In a thing editor 
  469. window, double-clicking on a part brings up an inspector window on 
  470. the part.) Double- clicking over the background does a select-all 
  471. operation. Non-sweep drag gestures over the background are used 
  472. for the "scroll" operation (reflected by a little hand cursor). All 
  473. operations except moving and selecting objects can also be invoked 
  474. via the menu.
  475.  
  476. Parts Bins
  477.  
  478. Primitive and previously constructed things are kept in a set of 
  479. hierarchically nested, iconic parts bins. The root of the hierarchy is 
  480. called ╥Top Bin╙. A special bin called ╥All Parts╙ contains icons for all 
  481. primitive and constructed things in the system and is the only parts 
  482. bin from which a thing may be deleted from the system. The user may 
  483. construct additional parts bins to organize his set of things as 
  484. desired. The icon for a given thing may reside in any number of parts 
  485. bins, allowing Things to be cross filed in a number of bins.
  486.  
  487. Editing Things
  488.  
  489. Most Things may be moved by dragging them with the mouse. 
  490. Several objects may be selected and dragged together. Such 
  491. interactions are accomplished by adding mouse constraints to the 
  492. location parts of the objects to be moved. If any of these locations is 
  493. fixed by a constraint of higher strength, that object cannot be moved. 
  494. It is possible to increase the strength of the mouse constraints using 
  495. the ThingLab II Control Panel. This is useful when one wishes to 
  496. move the PointAnchor.
  497.  
  498. Editing non-graphical values not quite so obvious. You specify 
  499. numbers by selecting one or more NumberPrinter or 
  500. NumberDisplayer things and typing digits. Constraints are 
  501. resatisfied as you type. Backspace deletes the last digit, the minus 
  502. sign changes the sign, and the period may be used to input floating 
  503. point quantities. Strings may by typed into TextThings in a similar 
  504. manner.
  505.  
  506. To draw bits into a FormDisplayer, use the yellow button (the red 
  507. button is used to select and move it). You may also bring up a fat-bits 
  508. editor on the form by using shift-yellow button.
  509.  
  510. As a last resort, you can edit the value of an object using a Smalltalk 
  511. inspector. This goes outside the normal constraint world, however, 
  512. so constraint satisfaction will not occur until you do something else 
  513. to trigger it. You can open an inspector by selecting a single object 
  514. and invoking the "inspect" menu item or by double-clicking over the 
  515. object. If there is no selection, invoking the "inspect" menu item will 
  516. open an inspector on the top-level thing.
  517.  
  518. Using Custom Constraints
  519.  
  520. A custom constraint allows the user to define a new constraint 
  521. directly from the direct manipulation interface. There are two-, 
  522. three-, and four-variable custom constraints. Initially, a custom 
  523. constraint does not constraint its variables in any way. Shift-clicking 
  524. on the custom constraint brings up a Constraint Definer view. The 
  525. user types in the methods of the constraint separated by blank lines. A 
  526. method consists of one or more assignment statements. The 
  527. constrained variables listed at the top of the view should be used in 
  528. these statements. It is also allowable to reference global variables 
  529. such as "Transcript". When done, the use invokes "accept" from the 
  530. menu and the constraint is installed. Since the constraint is usually 
  531. executed as soon as it is installed, the user should be sure that the 
  532. variables have reasonable values (i.e. not nil) before installing the 
  533. constraint. To remove a custom constraint, delete all the methods 
  534. and "accept" again. This will return it to its initial, unconstraining, 
  535. state.
  536.  
  537. The Module Compiler
  538.  
  539. The Module Compiler is invoked with the "make module" menu 
  540. command in a thing construction view. This changes the view to one 
  541. used to specify the parts that should be externally visible after the 
  542. module is compiled. In this view, parts to be externally visible are 
  543. displayed normally and all other parts are shown in gray. External 
  544. parts may be toggled by shift-clicking on them. When the external 
  545. parts have be designated, the "compile" menu command is invoked. 
  546. The compiler presents a picture giving feedback as it goes through 
  547. the compilation process. Then, the view is changed back to a thing 
  548. construction view, but now it shows the compiled module instead of 
  549. the original thing. You may interact with this module to verify that it 
  550. behaves correctly. The "view source" and "view module" menu 
  551. commands can be used to switch between the source thing and the 
  552. module compiled from it.
  553.  
  554. Warning: The Module Compiler has not been tested extensively and 
  555. almost certainly has lingering bugs.
  556.  
  557. The Debugger
  558.  
  559. The debugger allows the user to study the constraints of a thing 
  560. through a graphic display of the underlying constraint/dataflow 
  561. graph. It is invoked with the "debugger" menu command in the thing 
  562. construction view. The nodes in this constraint graph represent 
  563. variables and the arcs represent constraints. Variables are labeled 
  564. with their path and constraints are labeled with abbreviations 
  565. representing their strengths.
  566.  
  567. The graph is not presented all at once but rather in independent 
  568. subgraphs called partitions. By definition, there are no inter-
  569. partition constraints and thus each partition behaves independently 
  570. of all other partitions. The number of partitions is displayed in the 
  571. upper left corner of the debugger view along with two arrows. 
  572. Clicking on the arrows with the mouse cycles forward and backward 
  573. through the partitions.
  574.  
  575. Constraint arcs are labeled with arrow heads to show which 
  576. constraint method was selected by the planner for each constraint. If 
  577. the constraint is not currently satisfied, its arc is displayed in gray. 
  578. The debugger initially shows the dataflow graph for the current 
  579. solution. There may be multiple, equally good solutions. These may 
  580. be cycled through using the arrows. The first time one of the arrows 
  581. is pressed, all solutions are computed (which may take a while) and 
  582. then the number of solutions is displayed. Only the arrowheads and 
  583. gray/non-gray status of the constraint arcs changes when the 
  584. displayed solution changes.
  585.  
  586. Constraints and variables and be moved with the mouse to create a 
  587. pleasing and readable layout. In addition, several menu commands 
  588. help achieve a good layout. The "center constraints" command 
  589. centers constraint labels between the constrained variables. The tails 
  590. of constraints with only one variable, such as stay, mouse, and edit 
  591. constraints, are made to point away from the center of the constraint 
  592. graph in an attempt to keep them out of the way. The "layout" 
  593. command invokes a more powerful but slower graph layout 
  594. algorithm. The graph is redisplayed as the algorithm executes and 
  595. the user may press and hold the mouse button to force the layout 
  596. algorithm to terminate early.
  597.  
  598. Warning: The layout algorithm becomes very slow for large graphs. 
  599. However, even when nicely laid out, large graphs are difficult to 
  600. understand so perhaps some sort of modularity mechanism is needed 
  601. to limit the amount of detail presented to the user.
  602.  
  603. 5. Release Notes
  604.  
  605. This version of ThingLab II runs only on version 2.3 of Smalltalk-80 
  606. from ParcPlace Systems. It should, however, port fairly easily to 
  607. other standard Smalltalk-80 systems. For example, we ported an 
  608. earlier version to Tektronix Smalltalk in half a day. Unfortunately, it 
  609. would be difficult to port the system to Digitalk Smalltalk because in 
  610. their system the compiler classes are not available to the end-user 
  611. and the equation translator and module compiler construct and 
  612. manipulate Smalltalk parse trees.
  613.  
  614. This is the second release of ThingLab II. The first release was given 
  615. out to only a few other research laboratories. This version fixes a 
  616. number of the bugs and limitations of the first release and improves 
  617. performance considerably.
  618.  
  619. Although we haven't the resources to maintain ThingLab II, we are 
  620. definitely interested in your experiences with the system, including 
  621. bug reports and suggestions. Comments should be addressed to:
  622.  
  623.     John Maloney (jmaloney@june.cs.washington.edu)
  624.  
  625. who may also be reached at:
  626.  
  627.     Department of Computer Science and Engineering, FR-35
  628.     University of Washington
  629.     Seattle, WA  98195
  630.     USA
  631.  
  632. 6. References
  633.  
  634. The following are additional  references for ThingLab II. Pointers 
  635. into the general literature on constraint programming may be found 
  636. in each paper, although the bibliography of the CACM paper is the 
  637. most comprehensive.
  638.  
  639. Maloney, J., Borning, A., and Freeman-Benson, B. "Constraint 
  640. Technology for User Interface Construction in ThingLab II" In 
  641. OOPSLA '89 Proceedings, pp. 381-388.
  642.  
  643. Freeman-Benson, B. "A Module Mechanism for Constraints in 
  644. Smalltalk" In OOPSLA '89 Proceedings, pp. 389-396.
  645.  
  646. Freeman-Benson, B., Maloney, J., Borning, A. "The DeltaBlue 
  647. Algorithm: An Incremental Constraint Hierarchy Solver" CACM 
  648. 33:1 (January 1989), pp. 54-63. Available in expanded form as 
  649. Department of Computer Science and Engineering Technical Report 
  650. 89-08-06, University of Washington, Seattle, WA, 98195.
  651.  
  652. Appendix: Installing ThingLabII
  653.  
  654. The following three files should be filed in, in order:
  655.  
  656.     ThingLabII.v2.st
  657.     Things.v2.st
  658.     Demos.v2.st
  659.  
  660. This will take a while, perhaps as much as an hour on some 
  661. platforms. There is also an optional .form file to be placed in the 
  662. same directory as your image:
  663.  
  664.     ThingLabII.form
  665.  
  666. If available, this file is used to display a humorous picture when the 
  667. image is started.
  668.  
  669. Acknowledgements
  670.  
  671. The first version of ThingLab II was implemented from scratch by 
  672. Bjorn Freeman-Benson and John Maloney in about four months. It 
  673. was further developed and improved over the following year by John 
  674. Maloney. Alan Borning acted as high-level consultant and mentor.
  675.  
  676. ThingLab II incorporates many of the ideas from Alan Borning's 
  677. earlier constraint programming system, ThingLab, including 
  678. constraint hierarchies, merging, and the construction-set metaphor. 
  679. Spiritual ancestors include Gosling's thesis and Sutherland's 
  680. ground-breaking SketchPad system.
  681.  
  682. Apple Computer provided two Macintosh II computers and a one 
  683. year fellowship for John Maloney. IBM also supported John 
  684. Maloney for one year. An NSF fellowship supported Bjorn 
  685. Freeman-Benson. Additional funding was provided by NSF Grant 
  686. No. IRI-8803294 and the Washington Technology Center. We are 
  687. grateful to all for their support.
  688.